package com.doubao.common.config;

import io.lettuce.core.ClientOptions;
import io.lettuce.core.SocketOptions;
import io.lettuce.core.TimeoutOptions;
import io.lettuce.core.resource.ClientResources;
import io.lettuce.core.resource.DefaultClientResources;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;

import java.time.Duration;

/**
 * Lettuce客户端配置类
 * 提供更高性能和更强大的Redis连接池配置
 */
@Configuration
@Slf4j
@ConditionalOnProperty(name = "spring.data.redis.client-type", havingValue = "lettuce", matchIfMissing = true)
public class LettuceConfig {

    @Value("${spring.data.redis.host:192.168.194.206}")
    private String host;

    @Value("${spring.data.redis.port:6379}")
    private int port;

    @Value("${spring.data.redis.password:DoubaoAuthServiceJwtSecretKey0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ}")
    private String password;

    @Value("${spring.data.redis.database:0}")
    private int database;

    @Value("${spring.data.redis.lettuce.pool.max-active:8}")
    private int maxActive;

    @Value("${spring.data.redis.lettuce.pool.max-idle:8}")
    private int maxIdle;

    @Value("${spring.data.redis.lettuce.pool.min-idle:0}")
    private int minIdle;

    @Value("${spring.data.redis.lettuce.pool.max-wait:-1}")
    private long maxWait;

    @Value("${spring.data.redis.connect-timeout:2000}")
    private int connectTimeout;

    @Value("${spring.data.redis.timeout:1000}")
    private int commandTimeout;

    @Value("${spring.data.redis.retry.max-attempts:3}")
    private int maxRetryAttempts;

    @Value("${spring.data.redis.retry.delay:1000}")
    private long retryDelay;

    /**
     * 创建并配置Lettuce客户端资源
     */
    @Bean(destroyMethod = "shutdown")
    public ClientResources lettuceClientResources() {
        return DefaultClientResources.builder()
                .ioThreadPoolSize(4)                 // IO线程池大小
                .computationThreadPoolSize(4)        // 计算线程池大小
                .build();
    }

    /**
     * 创建并配置Redis连接池配置
     */
    @Bean
    public GenericObjectPoolConfig<?> lettucePoolConfig() {
        GenericObjectPoolConfig<?> poolConfig = new GenericObjectPoolConfig<>();
        poolConfig.setMaxTotal(maxActive);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxWait(Duration.ofMillis(maxWait));

        // 其他连接池配置
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        poolConfig.setTestWhileIdle(true);
        poolConfig.setTimeBetweenEvictionRuns(Duration.ofSeconds(30));

        return poolConfig;
    }

    /**
     * 创建并配置Redis连接工厂
     */
    @Bean
    @Primary
    public RedisConnectionFactory lettuceConnectionFactory(
            ClientResources lettuceClientResources,
            GenericObjectPoolConfig<?> lettucePoolConfig) {

        log.info("初始化优化版LettuceConnectionFactory，连接到 {}:{}, database: {}", host, port, database);

        // 创建Redis连接配置
        RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
        redisConfig.setHostName(host);
        redisConfig.setPort(port);
        if (password != null && !password.isEmpty()) {
            redisConfig.setPassword(password);
        }
        redisConfig.setDatabase(database);

        // 配置Socket选项
        SocketOptions socketOptions = SocketOptions.builder()
                .connectTimeout(Duration.ofMillis(connectTimeout))
                .keepAlive(true)
                .tcpNoDelay(true)
                .build();

        // 配置客户端选项
        ClientOptions clientOptions = ClientOptions.builder()
                .socketOptions(socketOptions)
                .timeoutOptions(TimeoutOptions.enabled(Duration.ofMillis(commandTimeout)))
                .autoReconnect(true)
                .disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS)
                .build();

        // 创建带连接池的Lettuce客户端配置
        LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                .poolConfig(lettucePoolConfig)
                .clientResources(lettuceClientResources)
                .clientOptions(clientOptions)
                .commandTimeout(Duration.ofMillis(commandTimeout))
                .build();

        // 创建连接工厂
        LettuceConnectionFactory factory = new LettuceConnectionFactory(redisConfig, clientConfig);

        // 设置共享本地连接
        factory.setShareNativeConnection(true);

        return factory;
    }
}